from PyQt4.QtGui import QApplication
from GameUI.MainWindow import MainWindow
from GameUI.View import *
from GameCore.GameCore import *

#from PyQt4 import QtCore, QtGui

SHOW	=	1

class SessionGame():
	
	#Session stage
	RUN		=		1000
	WAIT		=		1001
	PLAY		=		1002
	DONE		=		1003
	
	def __init__(self):
		pass
		
	def NewSession(self, table, idFirst):
		self.table = table
		#initing player in session
		self.session = Session(self.table.GetOrderSession(idFirst))
		self.stage = SessionGame.RUN
		self.stagePlayer = None
		self.idPlayer = None
		self.lastCard = None
		
		#first play
		return self.run(None, True)
		
	def run(self, cardPlay, attack):
		
		cardsInSession = self.session.cardsInSession
		for i in [self.session.Active, self.session.Support]:
			if i.GetStageInSession() == Player.PLAY:
				attacker = i
				break
		defender = self.session.Passive
		
		while 1:
			if attack:
				print "attack start"
				card = None
				change = False
				#attacker check card can play
				attacker.CheckAvailable(cardsInSession, defender.GetNumCards(), self.table.IsDeckEmpty())
				astage = attacker.GetStage()
				#change attacker if have
				if astage == Player.CANT_ATTACK or astage == Player.MUST_TAKE_CARDS:
					print "attacker cant attack", change
					if len(cardsInSession) >0:
						attacker = self.session.ChangeActive()
						print "changing", attacker
						if attacker <> None:
							if not change:
								change = True
							elif change:
								self.stage = SessionGame.DONE
								self.stagePlayer = astage
								return attack
						else:
							self.stage = SessionGame.DONE
							self.stagePlayer = astage
							return attack
					if not change:
						print "not change"
						self.stage = SessionGame.DONE
						self.stagePlayer = astage
						return attack
					else:
						attacker.CheckAvailable(cardsInSession, defender.GetNumCards(), self.table.IsDeckEmpty())
						astage = attacker.GetStage()
				#attacker  win
				if astage == Player.WIN:
					self.stage = SessionGame.DONE
					self.stagePlayer = astage
					return attack
				#attacker choose card
				elif astage == Player.CAN_ATTACK:
					#if attacker is human
					if attacker.GetType() == Player.PERSON:
						if self.stage <> SessionGame.PLAY:
							self.stage = SessionGame.WAIT
							return attack
						else:
							card = cardPlay
							if card in attacker.GetCardsCanPlay():
								self.stage = SessionGame.RUN
							else:
								self.stage = SessionGame.WAIT
								return attack
					#if attacker is bot
					else:
						card = attacker.ChooseCard(self.table.cardsDone)
				
				#TODO: draw card attack here
				controller = Controller()
				absPos = attacker.cards.GetAbsPos(card.GetID())
				print absPos
				if attacker.GetType() == Player.PERSON:
					controller.playerView.pushCard(absPos)
				else:
					controller.botView.pushCard(absPos,  'ATTACK',  'LEFT')
				print card
				
				#update information of all player and session after attack
				attacker.PlayCard(card)
				cardsInSession.append(card)
				for i in self.table.players:
					if i.GetType() <> Player.PERSON:
						if i.GetTypeInSession() in [Player.ACTIVE, Player.SUPPORT]:
							i.UpdateAI(card, True)
						else: i.UpdateAI(card, False)
				attack = False
				self.lastCard = card
				print "attack done"
			if not attack:
				print "defend start"
				#defender check card can play
				defender.CheckAvailable(self.lastCard, attacker.GetNumCards(), self.table.IsDeckEmpty())
				dstage = defender.GetStage()
				#defender have no card and deck have card
				if dstage == Player.MUST_TAKE_CARDS:
					#take card in deck
					self.table.TakeCardsInDeck(defender)
					defender.CheckAvailable(card, attacker.GetNumCards(), self.table.IsDeckEmpty())
					dstage = defender.GetStage()
				#defender cant defend
				if  dstage == Player.CANT_DEFEND:
					#update information of all player and session
					defender.ReceiveCard(cardsInSession)
					for i in self.table.players:
						if i.GetType() <> Player.PERSON:
							i.UpdateAI(cardsInSession, False, dstage)
					self.stage = SessionGame.DONE
					print self.stage == SessionGame.DONE
					self.stagePlayer = dstage
					return attack
				#defender win
				elif dstage == Player.WIN:
					self.stage = SessionGame.DONE
					self.stagePlayer = dstage
					return attack
				#can defend
				else:
					card = None
					#if defender is human
					if defender.GetType() == Player.PERSON:
						if self.stage <> SessionGame.PLAY:
							self.stage = SessionGame.WAIT
							return attack
						else:
							card = cardPlay
							if card in defender.GetCardsCanPlay():
								self.stage = SessionGame.RUN
							else:
								self.stage = SessionGame.WAIT
								return attack
					#if attacker is bot
					else:
						card = defender.ChooseCard(self.table.cardsDone)
					#TODO: draw card defend here
					controller = Controller()
					absPos = defender.cards.GetAbsPos(card.GetID())
					print absPos
					if defender.GetType() == Player.PERSON:
						controller.playerView.pushCard(absPos,  'DEFEND',  'LEFT')
					else:
						controller.botView.pushCard(absPos,  'DEFEND',  'RIGHT')
					print card
					
					#update information of all player and session after attack
					defender.PlayCard(card)
					cardsInSession.append(card)
					for i in self.table.players:
						if i.GetType() <> Player.PERSON:
							if i.GetTypeInSession() in [Player.ACTIVE, Player.SUPPORT]:
								i.UpdateAI(card, False)
							else: i.UpdateAI(card, True)
				attack = True
				self.lastCard = card
				print "defend done"
				
	def FinishSession(self):
		print "New session"
		if self.stagePlayer == Player.WIN: return
		else:
			self.table.TakeCardsInDeck(self.session.Active)
			self.table.TakeCardsInDeck(self.session.Passive)
			if self.session.Support <> None:
				self.table.TakeCardsInDeck(self.session.Support)
			if self.session.Deactive <> None:
				self.table.TakeCardsInDeck(self.session.Deactive)
			
	
class Controller(object):
	
	class __impl:
		""" Implementation of the singleton interface """
		
		def __init__(self):
			self.table = None
			self.session = None
			self.first = None
			self.attack = None
			
		def NewGame(self):
			self.window = MainWindow()
			self.window.show()
					
			#Delete all variable if have
			if self.table <> None:
				del self.table
			if self.session <> None:
				del self.session
				
			#Make new Table()
			self.table = Table()
			
			#Serve card for player
			self.table.ServeCards()
			
			#id first player in session
			self.first = self.table.GetFirstPlayer()
			
			#Show cards
			deckCardView = DeckView(self.table.GetSpecial(),  self.window)
			for i in self.table.GetPlayers():
				if i.GetType() == Player.PERSON:
					self.playerView = CardsView(i.cards, self.window)
				elif SHOW:
					self.botView = CardsView(i.cards, self.window, 1)
			#Run game
			self.RunGame()
			
		def RunGame(self):
			#Init first session
			self.session = SessionGame()
			self.attack = self.session.NewSession(self.table, self.first)
		
		def handleEvent(self, idCard):
			if self.session.stage == SessionGame.WAIT:
				player = self.table.players[0]
				self.session.stage = SessionGame.PLAY
				self.attack = self.session.run(player.cards.GetCard(idCard), self.attack)
				if self.session.stage == SessionGame.DONE:
					self.session.FinishSession()
#					self.window.playingFrameLeft.erase()
#					self.window.playingFrameRight.erase()
#					self.window.makeSessionLayout()
					for i in self.table.GetPlayers():
						if i.GetType() == Player.PERSON:
							print "Person delete"
							print self.playerView.close()
							self.playerView.clearLayout()
#							self.playerView.setVisible(False)
#							self.playerView.destroy(True, True)
							self.playerView = CardsView(i.cards, self.window)
						elif SHOW:
							print "Bot delete"
							print self.botView.close()
							self.botView.clearLayout()
#							self.botView.setVisible(False)
#							self.botView.destroy(True, True)
							self.botView = CardsView(i.cards, self.window, 1)
					if self.session.stagePlayer == Player.CANT_DEFEND:
						self.first = (self.first+2)%self.table.GetNumPlayers()
					else:
						self.first = (self.first+1)%self.table.GetNumPlayers()
					self.session.NewSession(self.table, self.first)
	
	# storage for the instance reference
	__instance = None
	
	
	def __init__(self):
		""" Create singleton instance """
		# Check whether we already have an instance
		if Controller.__instance is None:
		    # Create and remember instance
		    Controller.__instance = Controller.__impl()

		# Store instance reference as the only member in the handle
		self.__dict__['_Controller__instance'] = Controller.__instance
		
	def __getattr__(self, attr):
		""" Delegate access to implementation """
		return getattr(self.__instance, attr)

	def __setattr__(self, attr, value):
		""" Delegate access to implementation """
		return setattr(self.__instance, attr, value)
